package com.agile.leetcode.easy.robotsim;

import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 机器人在一个无限大小的 XY 网格平面上行走，从点 (0, 0) 处开始出发，面向北方。该机器人可以接收以下三种类型的命令 commands ：
 *
 *     -2 ：向左转 90 度
 *     -1 ：向右转 90 度
 *     1 <= x <= 9 ：向前移动 x 个单位长度
 *
 * 在网格上有一些格子被视为障碍物 obstacles 。第 i 个障碍物位于网格点  obstacles[i] = (xi, yi) 。
 *
 * 机器人无法走到障碍物上，它将会停留在障碍物的前一个网格方块上，但仍然可以继续尝试进行该路线的其余部分。
 *
 * 返回从原点到机器人所有经过的路径点（坐标为整数）的最大欧式距离的平方。（即，如果距离为 5 ，则返回 25 ）
 *
 *
 * 注意：
 *
 *     北表示 +Y 方向。
 *     东表示 +X 方向。
 *     南表示 -Y 方向。
 *     西表示 -X 方向。
 *
 *
 *
 * 示例 1：
 *
 * 输入：commands = [4,-1,3], obstacles = []
 * 输出：25
 * 解释：
 * 机器人开始位于 (0, 0)：
 * 1. 向北移动 4 个单位，到达 (0, 4)
 * 2. 右转
 * 3. 向东移动 3 个单位，到达 (3, 4)
 * 距离原点最远的是 (3, 4) ，距离为 32 + 42 = 25
 *
 * 示例 2：
 *
 * 输入：commands = [4,-1,4,-2,4], obstacles = [[2,4]]
 * 输出：65
 * 解释：机器人开始位于 (0, 0)：
 * 1. 向北移动 4 个单位，到达 (0, 4)
 * 2. 右转
 * 3. 向东移动 1 个单位，然后被位于 (2, 4) 的障碍物阻挡，机器人停在 (1, 4)
 * 4. 左转
 * 5. 向北走 4 个单位，到达 (1, 8)
 * 距离原点最远的是 (1, 8) ，距离为 12 + 82 = 65
 *
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/walking-robot-simulation
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * @Author KD
 * @Date 2021/2/1 9:40
 */
public class RobotSim {
    public static void main(String[] args) {
        RobotSim sim=new RobotSim();
        int[] commands={4,-1,4,-2,4};
        int[][] obstacles={{2,4}};
        int i = sim.robotSim(commands, obstacles);
        System.out.println(i);
    }
    public int robotSim(int[] commands, int[][] obstacles) {
        // 记录当前坐标
        Point point = new Point(0, 0);
        List<Point> list = new ArrayList<>();
        for (int[] obstacle : obstacles) {
            list.add(new Point(obstacle[0], obstacle[1]));
        }
        // 拿到方向
        // 0 初始化为正北方向
        int direct = 0;
        // 遍历命令
        for (int command : commands) {
            switch (command) {
                case -1:
                    direct = direct + 1;
                    if (direct==4||direct==-4){
                        direct=0;
                    }
                    continue;
                case -2:
                    direct = direct - 1;
                    if (direct==4||direct==-4){
                        direct=0;
                    }
                    continue;
            }
            if (direct == 1 || direct == -3) {
                int x1 = point.x;
                point.x = x1 + command;
                List<Point> collect = list.stream().filter(x -> {
                    if (x.x > x1 && x.x < point.x && x.y == point.y) {
                        return true;
                    }
                    return false;
                }).collect(Collectors.toList());
                if (collect.size() > 0) {
                    Collections.sort(collect, new Comparator<Point>() {
                        @Override
                        public int compare(Point o1, Point o2) {
                            return o1.x - o2.x;
                        }
                    });
                    Point point1 = collect.get(0);
                    point.x = point1.x - 1;
                }
            }
            if (direct == 0) {
                int y = point.y;
                point.y = y + command;
                List<Point> collect = list.stream().filter(x -> {
                    if (x.x == point.x && x.y > y && x.y < point.y) {
                        return true;
                    }
                    return false;
                }).collect(Collectors.toList());
                if (collect.size() > 0) {
                    Collections.sort(collect, new Comparator<Point>() {
                        @Override
                        public int compare(Point o1, Point o2) {
                            return o1.y - o2.y;
                        }
                    });
                    Point point1 = collect.get(0);
                    point.y = point1.y - 1;
                }
            }
            if (direct == 2 || direct == -2) {
                int y = point.y;
                point.y = y - command;
                List<Point> collect = list.stream().filter(x -> {
                    if (x.x == point.x && x.y < y && x.y > point.y) {
                        return true;
                    }
                    return false;
                }).collect(Collectors.toList());
                if (collect.size() > 0) {
                    Collections.sort(collect, new Comparator<Point>() {
                        @Override
                        public int compare(Point o1, Point o2) {
                            return o2.y - o1.y;
                        }
                    });
                    Point point1 = collect.get(0);
                    point.y = point1.y + 1;
                }
            }
            if (direct == -1 || direct == 3) {
                int x1 = point.x;
                point.x = x1 - command;
                List<Point> collect = list.stream().filter(x -> {
                    if (x.x < x1 && x.x > point.x && x.y == point.y) {
                        return true;
                    }
                    return false;
                }).collect(Collectors.toList());
                if (collect.size() > 0) {
                    Collections.sort(collect, new Comparator<Point>() {
                        @Override
                        public int compare(Point o1, Point o2) {
                            return o2.x - o1.x;
                        }
                    });
                    point.x = collect.get(0).x + 1;
                }
            }
        }
        return point.x * point.x + point.y * point.y;
    }
}
